﻿#include "stdafx.h"
#include "PhysScriptBinder.h"
#include "NxVehicleDesc.h"
#include "Car.h"

#include "DebugAssert.h"

_NAMESPACE_BEGIN

static PhysXPrimitive* NxShape_GetPrimitive(NxShape* self)
{
	return (PhysXPrimitive*)self->userData;
}

static PhysPlane* New_PhysPlane()
{
	return new PhysPlane;
}

static PhysTerrain* New_PhysTerrain()
{
	return new PhysTerrain;
}

static PhysCar* New_PhysCar(CONST_REF(string)name)
{
	return new PhysCar(name);
}

static PhysBox* New_PhysBox()
{
	return new PhysBox;
}

PhysicsLib_ScriptBinder::PhysicsLib_ScriptBinder()
{
	asIScriptEngine* engine=AngelScriptBinder::Instance()->GetEngine();
	int r;

	BindPhysX(engine);

	///Shape_Desc
	r = engine->RegisterObjectType("Shape_Desc", sizeof(Shape_Desc),asOBJ_REF); assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(Shape_Desc)
	TYPEMETHODS(Shape_Desc)

	///Cube_Desc
	r = engine->RegisterObjectType("Cube_Desc", sizeof(Cube_Desc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(Cube_Desc)
	DECLARE_VALUE_DERIVE(Cube_Desc,Shape_Desc)
	TYPEMETHODS(Cube_Desc)		

	///PhysXPrimitive
	r=engine->RegisterObjectType("PhysXPrimitive",sizeof(PhysXPrimitive), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PhysXPrimitive)
	TYPEMETHODS(PhysXPrimitive)		
	r = engine->RegisterObjectMethod("NxShape","PhysXPrimitive@ GetPrimitive()",asFUNCTION(NxShape_GetPrimitive), asCALL_CDECL_OBJLAST);	 assert( r >= 0 );

	//CubeShape
	r=engine->RegisterObjectType("CubeShape",sizeof(CubeShape), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(CubeShape)
	DECLARE_DERIVE(CubeShape,PhysXPrimitive)
	TYPEMETHODS(CubeShape)		

	///Sphere_Desc
	r = engine->RegisterObjectType("Sphere_Desc", sizeof(Sphere_Desc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(Sphere_Desc)	
	DECLARE_VALUE_DERIVE(Sphere_Desc,Shape_Desc)
	TYPEMETHODS(Sphere_Desc)

	///SphereShape
	r=engine->RegisterObjectType("SphereShape",sizeof(SphereShape), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(SphereShape)
	DECLARE_DERIVE(SphereShape,PhysXPrimitive)
	TYPEMETHODS(SphereShape)		

	///Capsule_Desc
	r = engine->RegisterObjectType("Capsule_Desc", sizeof(Capsule_Desc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(Capsule_Desc)	
	DECLARE_VALUE_DERIVE(Capsule_Desc,Shape_Desc)
	TYPEMETHODS(Capsule_Desc)

	///CapsuleShape
	r=engine->RegisterObjectType("CapsuleShape",sizeof(CapsuleShape), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(CapsuleShape)
	DECLARE_DERIVE(CapsuleShape,PhysXPrimitive)
	TYPEMETHODS(CapsuleShape)		

	///Wheel_Desc
	r = engine->RegisterObjectType("Wheel_Desc", sizeof(Wheel_Desc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(Wheel_Desc)	
	DECLARE_VALUE_DERIVE(Wheel_Desc,Shape_Desc)
	TYPEMETHODS(Wheel_Desc)

	///WheelShape
	r=engine->RegisterObjectType("WheelShape",sizeof(WheelShape), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(WheelShape)
	DECLARE_DERIVE(WheelShape,PhysXPrimitive)
	TYPEMETHODS(WheelShape)	

	///Plane_Desc
	r = engine->RegisterObjectType("Plane_Desc", sizeof(Plane_Desc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(Plane_Desc)	
	DECLARE_VALUE_DERIVE(Plane_Desc,Shape_Desc)
	TYPEMETHODS(Plane_Desc)

	///PlaneShape
	r=engine->RegisterObjectType("PlaneShape",sizeof(PlaneShape), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PlaneShape)
	DECLARE_DERIVE(PlaneShape,PhysXPrimitive)
	TYPEMETHODS(PlaneShape)	

	///Terrain_Desc
	r = engine->RegisterObjectType("Terrain_Desc", sizeof(Terrain_Desc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(Terrain_Desc)	
	DECLARE_VALUE_DERIVE(Terrain_Desc,Shape_Desc)
	TYPEMETHODS(Terrain_Desc)

	///PhysXObj
	r = engine->RegisterObjectType("PhysXObj",sizeof(PhysXObj), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PhysXObj)
	TYPEMETHODS(PhysXObj)

	///PhysPlane
	r = engine->RegisterObjectType("PhysPlane",sizeof(PhysPlane), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PhysPlane)
	DECLARE_DERIVE(PhysPlane,PhysXObj)
	TYPEMETHODS(PhysPlane)
	r=engine->RegisterGlobalFunction("PhysPlane@ New_PhysPlane()",asFUNCTION(New_PhysPlane),asCALL_CDECL);assert( r >= 0 );

	///PhysTerrain
	r = engine->RegisterObjectType("PhysTerrain",sizeof(PhysTerrain), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PhysTerrain)
	DECLARE_DERIVE(PhysTerrain,PhysXObj)
	TYPEMETHODS(PhysTerrain)
	r=engine->RegisterGlobalFunction("PhysTerrain@ New_PhysTerrain()",asFUNCTION(New_PhysTerrain),asCALL_CDECL);assert( r >= 0 );

	///NxVehicleDesc
	r = engine->RegisterObjectType("NxVehicleDesc", sizeof(NxVehicleDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(NxVehicleDesc)	
	TYPEMETHODS(NxVehicleDesc)

	///PhysCar
	r = engine->RegisterObjectType("PhysCar",sizeof(PhysCar), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PhysCar)
	DECLARE_DERIVE(PhysCar,PhysXObj)
	TYPEMETHODS(PhysCar)
	r=engine->RegisterGlobalFunction("PhysCar@ New_PhysCar(const string&in)",asFUNCTION(New_PhysCar),asCALL_CDECL);assert( r >= 0 );

	///PhysBox
	r = engine->RegisterObjectType("PhysBox",sizeof(PhysBox), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(PhysBox)
	DECLARE_DERIVE(PhysBox,PhysXObj)
	TYPEMETHODS(PhysBox)
	r=engine->RegisterGlobalFunction("PhysBox@ New_PhysBox()",asFUNCTION(New_PhysBox),asCALL_CDECL);assert( r >= 0 );

	///PhysicsManager
	r = engine->RegisterObjectType("PhysicsManager",sizeof(PhysicsManager), asOBJ_REF|asOBJ_NOHANDLE );	assert( r >= 0 );
	TYPEMETHODS(PhysicsManager)
	r = engine->RegisterGlobalProperty("PhysicsManager PhysicsManager_I",PhysicsManager::Instance() );	 assert( r >= 0 );


	//TriggerEvent
	r=engine->RegisterObjectType("TriggerEvent",sizeof(TriggerEvent), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(TriggerEvent)
	DECLARE_DERIVE(TriggerEvent,ASEvent)
	TYPEMETHODS(TriggerEvent)			
	r=engine->RegisterGlobalFunction("TriggerEvent@ New_TriggerEvent()",asFUNCTION(New_Type<TriggerEvent>), asCALL_CDECL);	 assert( r >= 0 );

	//TriggerInfor
	r = engine->RegisterObjectType("TriggerInfor", sizeof(TriggerInfor), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(TriggerInfor)
	r = engine->RegisterObjectProperty("TriggerInfor", "NxShape@ triggerShape", offsetof(TriggerInfor, triggerShape)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("TriggerInfor", "NxShape@ otherShape", offsetof(TriggerInfor, otherShape)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("TriggerInfor", "int status", offsetof(TriggerInfor, status)); assert( r >= 0 );

	r = engine->RegisterObjectMethod("TriggerEvent","void call(const TriggerInfor&in)",asMETHODPR(TriggerEvent,callEvent,(CONST_REF(TriggerInfor)),void), asCALL_THISCALL);	 assert( r >= 0 );

	//TriggerReport
	r = engine->RegisterObjectType("TriggerReport", sizeof(TriggerReport), asOBJ_REF|asOBJ_NOHANDLE); assert( r >= 0 );
	r = engine->RegisterObjectProperty("TriggerReport", "TriggerEvent event", offsetof(TriggerReport, event)); assert( r >= 0 );
	r = engine->RegisterGlobalProperty("TriggerReport TriggerReport_I",TriggerReport::Instance() );	 assert( r >= 0 );

	r = engine->RegisterEnum("TriggerStatus"); assert( r >= 0 );
	r = engine->RegisterEnumValue("TriggerStatus","TRIGGER_ENTER",TRIGGER_ENTER);
	r = engine->RegisterEnumValue("TriggerStatus","TRIGGER_LEAVE",TRIGGER_LEAVE);

	//TriggerListener
	r = engine->RegisterInterface("TriggerListener");
	r = engine->RegisterInterfaceMethod("TriggerListener","void OnTriggerReport(const TriggerInfor&in infor)");	 assert( r >= 0 );
}

//默认构造
static void NxVec3DefaultConstructor(NxVec3 *self)
{
	new(self) NxVec3();
}

//拷贝构造
static void NxVec3CopyConstructor(const NxVec3 &other, NxVec3 *self)
{
	new(self) NxVec3(other);
}

//来自Ogre::Vector3的构造
static void NxVec3FromVector3Constructor(const Vector3 &other, NxVec3 *self)
{
	new(self) NxVec3();
	*self=*(NxVec3*)&other;
}

//初始化参数构造
static void NxVec3InitConstructor(float x, float y, float z, Vector3 *self)
{
	new(self) NxVec3(x,y,z);
}

//转换
static NxVec3& castVector3ToNxVec3(Vector3& f3,NxVec3& self)
{
	self=*(NxVec3*)&f3;
	return self;
}

static Vector3& castNxVec3ToVector3(NxVec3& v3,Vector3& self)
{
	self=*(Vector3*)&v3;
	return self;
}


static void NxActorDesc_SetBodyDesc(NxActorDesc* self,const NxBodyDesc& body)
{
	self->body=&body;
}

static void NxActorDesc_AddShape(NxActorDesc* self,NxShapeDesc& shape)
{
	self->shapes.pushBack(&shape);
}

static NxActor *NxScene_createActor(const NxActorDescBase& in,NxScene* self)
{
	NxActor* p=self->createActor(in);
	assert(p);
	return p;
}

//setRestitution会偶尔失灵，所以只好检查一下
static void NxMaterial_setRestitution(float v,NxMaterial* self)
{
	while(abs(self->getRestitution()-v)>0.001f)
	{
		self->setRestitution(v);
	}
}

static void NxMaterial_setStaticFriction(float v,NxMaterial* self)
{
	while(abs(self->getStaticFriction()-v)>0.001f)
	{
		self->setStaticFriction(v);
	}
}

static void NxMaterial_setDynamicFriction(float v,NxMaterial* self)
{
	while(abs(self->getDynamicFriction()-v)>0.001f)
	{
		self->setDynamicFriction(v);
	}
}

static asIScriptObject* NxActor_GetScrptObj(NxActor* self)
{
 	NxShape*const * pshapes=self->getShapes();
 	if(pshapes[0]->userData)
 	{
 		NxShape* psh=self->getShapes()[0];
 		PhysXPrimitive* pprimitive=(PhysXPrimitive*)self->getShapes()[0]->userData;
 		asIScriptObject* p=pprimitive->GetOwner()->GetScriptObj();
 		p->AddRef();
 		return p;
 	}

 	return NULL;
}
static NxShape* NxActor_getShape(NxActor* self,int index)
{
	return self->getShapes()[index];
}
static NxVec3 NxVec3_negate(NxVec3* self)
{
	return -*self;
}

void PhysicsLib_ScriptBinder::BindPhysX( asIScriptEngine* engine )
{
	int r;

	//NxVec3
	r = engine->RegisterObjectType("NxVec3", sizeof(NxVec3), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( r >= 0 );		
	r = engine->RegisterObjectProperty("NxVec3", "float x", offsetof(NxVec3, x)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("NxVec3", "float y", offsetof(NxVec3, y)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("NxVec3", "float z", offsetof(NxVec3, z)); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("NxVec3", asBEHAVE_CONSTRUCT,  "void f()",                     asFUNCTION(NxVec3DefaultConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("NxVec3", asBEHAVE_CONSTRUCT,  "void f(const NxVec3 &in)",       asFUNCTION(NxVec3CopyConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectBehaviour("NxVec3", asBEHAVE_CONSTRUCT,  "void f(float, float, float)",  asFUNCTION(NxVec3InitConstructor), asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxVec3", "NxVec3 &opAssign(const Vector3 &in)",asFUNCTION(castVector3ToNxVec3), asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectMethod("Vector3", "Vector3 &opAssign(const NxVec3 &in)",asFUNCTION(castNxVec3ToVector3), asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxVec3", "NxVec3 opNeg()",asFUNCTION(NxVec3_negate), asCALL_CDECL_OBJLAST); assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxVec3","float normalize()",asMETHOD(NxVec3,normalize),asCALL_THISCALL);	 assert( r >= 0 );

	//NxMat33
	r = engine->RegisterObjectType("NxMat33", sizeof(NxMat33), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( r >= 0 );		
	DECLARE_CONSTRUCTOR(NxMat33)			
	r = engine->RegisterObjectMethod("NxMat33","void rotX(float)",asMETHOD(NxMat33,rotX),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMat33","void rotY(float)",asMETHOD(NxMat33,rotY),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMat33","void rotZ(float)",asMETHOD(NxMat33,rotZ),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMat33","void multiply(const NxVec3 &in, NxVec3 &out)",asMETHODPR(NxMat33,multiply,(const NxVec3&,NxVec3&)const,void),asCALL_THISCALL);

	//NxMat34
	r = engine->RegisterObjectType("NxMat34", sizeof(NxMat34), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( r >= 0 );		
	DECLARE_CONSTRUCTOR(NxMat34)		
	r = engine->RegisterObjectProperty("NxMat34", "NxVec3 t", offsetof(NxMat34,t)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("NxMat34", "NxMat33 M", offsetof(NxMat34,M)); assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMat34","void multiply(const NxVec3 &in, NxVec3 &out)",asMETHODPR(NxMat34,multiply,(const NxVec3&,NxVec3&)const,void),asCALL_THISCALL);	 assert( r >= 0 );
	//r = engine->RegisterObjectMethod("NxMat34","void getColumnMajor44(D3DXMATRIX &out)",asMETHODPR(NxMat34,getColumnMajor44,(NxF32 d[4][4])const,void),asCALL_THISCALL);	 assert( r >= 0 );
	//r = engine->RegisterObjectMethod("NxMat34","void setColumnMajor44(const D3DXMATRIX &in)",asMETHODPR(NxMat34,setColumnMajor44,(const NxF32 d[4][4]),void),asCALL_THISCALL);	 assert( r >= 0 );
	
	///NxQuat
	r = engine->RegisterObjectType("NxQuat", sizeof(NxQuat), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( r >= 0 );		
	DECLARE_CONSTRUCTOR(NxQuat)		
	r = engine->RegisterObjectMethod("NxQuat","void fromAngleAxis(float,NxVec3&in)",asMETHODPR(NxQuat,fromAngleAxis,(float,CONST_REF(NxVec3)),void),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxQuat","NxVec3 rot(const NxVec3&in)",asMETHOD(NxQuat,rot),asCALL_THISCALL);	 assert( r >= 0 );		
	r = engine->RegisterObjectMethod("NxQuat","void multiply(const NxQuat&in,const NxQuat&in)",asMETHODPR(NxQuat,multiply,(CONST_REF(NxQuat),CONST_REF(NxQuat)),void),asCALL_THISCALL);	 assert( r >= 0 );		

	//NxShapeDesc这些基类结构都声明为引用类型，因为这些是各个接口接受的，而他们的具体子类用值类型、实现自动垃圾回收，
	//到父类的转换使用asBEHAVE_FACTORY的方法而不是隐式转换

	//NxShapeDesc
	r = engine->RegisterObjectType("NxShapeDesc", sizeof(NxShapeDesc), asOBJ_REF); assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(NxShapeDesc)
	TYPEMETHODS(NxShapeDesc)
	//r = engine->RegisterObjectProperty("NxShapeDesc", "NxU32 shapeFlags", offsetof(NxShapeDesc,shapeFlags)); assert( r >= 0 );
	
	//NxBoxShapeDesc
	r = engine->RegisterObjectType("NxBoxShapeDesc", sizeof(NxBoxShapeDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(NxBoxShapeDesc)
	DECLARE_VALUE_DERIVE(NxBoxShapeDesc,NxShapeDesc)
	TYPEMETHODS(NxBoxShapeDesc)		

	//NxPlaneShapeDesc
	r = engine->RegisterObjectType("NxPlaneShapeDesc", sizeof(NxPlaneShapeDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );	
	DECLARE_CONSTRUCTOR(NxPlaneShapeDesc)
	DECLARE_VALUE_DERIVE(NxPlaneShapeDesc,NxShapeDesc)
	TYPEMETHODS(NxPlaneShapeDesc)

	//NxActorDescBase
	r = engine->RegisterObjectType("NxActorDescBase", sizeof(NxActorDescBase),asOBJ_REF); assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(NxActorDescBase)
	TYPEMETHODS(NxActorDescBase)

	//NxBodyDesc
	r = engine->RegisterObjectType("NxBodyDesc", sizeof(NxBodyDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(NxBodyDesc)

	//NxActorDesc
	r = engine->RegisterObjectType("NxActorDesc", sizeof(NxActorDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(NxActorDesc)
	DECLARE_VALUE_DERIVE(NxActorDesc,NxActorDescBase)
	TYPEMETHODS(NxActorDesc)

	//NxSceneDesc
	r = engine->RegisterObjectType("NxSceneDesc", sizeof(NxSceneDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );	
	DECLARE_CONSTRUCTOR(NxSceneDesc)
	r = engine->RegisterObjectProperty("NxSceneDesc", "NxVec3 gravity", offsetof(NxSceneDesc,gravity)); assert( r >= 0 );

	//NxMaterialDesc
	r = engine->RegisterObjectType("NxMaterialDesc", sizeof(NxMaterialDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	DECLARE_CONSTRUCTOR(NxMaterialDesc)
	r = engine->RegisterObjectProperty("NxMaterialDesc", "float restitution", offsetof(NxMaterialDesc,restitution)); assert( r >= 0 );
	r = engine->RegisterObjectProperty("NxMaterialDesc", "float staticFriction", offsetof(NxMaterialDesc,staticFriction)); assert( r >= 0 ); 
	r = engine->RegisterObjectProperty("NxMaterialDesc", "float dynamicFriction", offsetof(NxMaterialDesc,dynamicFriction)); assert( r >= 0 ); 

	//NxBodyFlag
	r=engine->RegisterEnum("NxBodyFlag"); assert( r >= 0 );
	r=engine->RegisterEnumValue("NxBodyFlag","NX_BF_KINEMATIC",NX_BF_KINEMATIC);
	r=engine->RegisterEnumValue("NxBodyFlag","NX_BF_FROZEN_ROT",NX_BF_FROZEN_ROT );
	r=engine->RegisterEnumValue("NxBodyFlag","NX_BF_DISABLE_GRAVITY",NX_BF_DISABLE_GRAVITY );

	//NxForceMode
	r=engine->RegisterEnum("NxForceMode"); assert( r >= 0 );
	r=engine->RegisterEnumValue("NxForceMode","NX_FORCE",NX_FORCE);
	r=engine->RegisterEnumValue("NxForceMode","NX_IMPULSE",NX_IMPULSE );
	r=engine->RegisterEnumValue("NxForceMode","NX_VELOCITY_CHANGE",NX_VELOCITY_CHANGE );
	//NxContactPairFlag
	r=engine->RegisterEnum("NxContactPairFlag"); assert( r >= 0 );
	r=engine->RegisterEnumValue("NxContactPairFlag","NX_IGNORE_PAIR",NX_IGNORE_PAIR );		 
	r=engine->RegisterEnumValue("NxContactPairFlag","NX_NOTIFY_ON_START_TOUCH",NX_NOTIFY_ON_START_TOUCH );
	r=engine->RegisterEnumValue("NxContactPairFlag","NX_NOTIFY_FORCES",NX_NOTIFY_FORCES );
	r=engine->RegisterEnumValue("NxContactPairFlag","NX_NOTIFY_ON_TOUCH_FORCE_THRESHOLD",NX_NOTIFY_ON_TOUCH_FORCE_THRESHOLD );		
	r=engine->RegisterEnumValue("NxContactPairFlag","NX_NOTIFY_ON_START_TOUCH_FORCE_THRESHOLD",NX_NOTIFY_ON_START_TOUCH_FORCE_THRESHOLD );
	r=engine->RegisterEnumValue("NxContactPairFlag","NX_NOTIFY_ON_END_TOUCH",NX_NOTIFY_ON_END_TOUCH );

	///NxActorFlag
	r=engine->RegisterEnum("NxActorFlag"); assert( r >= 0 );
	r=engine->RegisterEnumValue("NxActorFlag","NX_AF_DISABLE_COLLISION",NX_AF_DISABLE_COLLISION);

	//NxShapeFlag
	r=engine->RegisterEnum("NxShapeFlag"); assert( r >= 0 );
	r=engine->RegisterEnumValue("NxShapeFlag","NX_TRIGGER_ON_STAY",NX_TRIGGER_ON_STAY);
	r=engine->RegisterEnumValue("NxShapeFlag","NX_TRIGGER_ON_LEAVE",NX_TRIGGER_ON_LEAVE );
	r=engine->RegisterEnumValue("NxShapeFlag","NX_TRIGGER_ON_ENTER",NX_TRIGGER_ON_ENTER );
	r=engine->RegisterEnumValue("NxShapeFlag","NX_TRIGGER_ENABLE",NX_TRIGGER_ENABLE );
	r=engine->RegisterEnumValue("NxShapeFlag","NX_SF_DISABLE_COLLISION",NX_SF_DISABLE_COLLISION );
	r=engine->RegisterEnumValue("NxShapeFlag","NX_SF_DISABLE_RAYCASTING",NX_SF_DISABLE_RAYCASTING );

	//NxShapeType
	r=engine->RegisterEnum("NxShapeType"); assert( r >= 0 );
	r=engine->RegisterEnumValue("NxShapeType","NX_SHAPE_SPHERE",NX_SHAPE_SPHERE);
	r=engine->RegisterEnumValue("NxShapeType","NX_SHAPE_BOX",NX_SHAPE_BOX);
	r=engine->RegisterEnumValue("NxShapeType","NX_SHAPE_CAPSULE",NX_SHAPE_CAPSULE);

	//NxShape
	r = engine->RegisterObjectType("NxShape",sizeof(NxShape), asOBJ_REF );	assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","void setFlag(NxShapeFlag,bool)",asMETHOD(NxShape,setFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","int getFlag(NxShapeFlag)",asMETHOD(NxShape,getFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","NxShapeType getType()",asMETHOD(NxShape,getType), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","void setMaterial(uint16)",asMETHOD(NxShape,setMaterial), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","NxMat34 getGlobalPose()",asMETHOD(NxShape,getGlobalPose), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","NxMat34 getLocalPose()",asMETHOD(NxShape,getLocalPose), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","void setGroup(uint)",asMETHOD(NxShape,setGroup), asCALL_THISCALL);	 assert( r >= 0 );

	DECLARE_EMPTY_ADD_RELEASE_REF(NxShape)

	//NxWheelShape
	r = engine->RegisterObjectType("NxWheelShape", sizeof(NxWheelShape), asOBJ_REF); assert( r >= 0 );		
	DECLARE_DERIVE(NxWheelShape,NxShape)
	r = engine->RegisterObjectMethod("NxWheelShape","void setMotorTorque(float)",asMETHOD(NxWheelShape,setMotorTorque),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxWheelShape","float getMotorTorque()",asMETHOD(NxWheelShape,getMotorTorque),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxWheelShape","void setSteerAngle(float)",asMETHOD(NxWheelShape,setSteerAngle),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxWheelShape","float getSteerAngle()",asMETHOD(NxWheelShape,getSteerAngle),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxWheelShape","void setBrakeTorque(float)",asMETHOD(NxWheelShape,setBrakeTorque),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxWheelShape","float getBrakeTorque()",asMETHOD(NxWheelShape,getBrakeTorque),asCALL_THISCALL);	 assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(NxWheelShape)

	//NxActor 
	r=engine->RegisterObjectType("NxActor",sizeof(NxActor), asOBJ_REF);	assert( r >= 0 ); 
	DECLARE_EMPTY_ADD_RELEASE_REF(NxActor)
	r = engine->RegisterObjectMethod("NxActor","EventHandler@ GetScrptObj()",asFUNCTION(NxActor_GetScrptObj), asCALL_CDECL_OBJLAST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void addForce(const NxVec3& in,NxForceMode,bool)",asMETHOD(NxActor,addForce), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void addForceAtPos(const NxVec3& in,const NxVec3& in,NxForceMode,bool)",asMETHOD(NxActor,addForceAtPos), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void addTorque(const NxVec3& in,NxForceMode,bool)",asMETHOD(NxActor,addTorque), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setLinearDamping(float)",asMETHOD(NxActor,setLinearDamping), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setAngularDamping(float)",asMETHOD(NxActor,setAngularDamping), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void raiseBodyFlag(uint)",asMETHOD(NxActor,raiseBodyFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void clearBodyFlag(NxBodyFlag)",asMETHOD(NxActor,clearBodyFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","bool readBodyFlag(NxBodyFlag)",asMETHOD(NxActor,readBodyFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void clearActorFlag(NxActorFlag)",asMETHOD(NxActor,clearActorFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void raiseActorFlag(NxActorFlag)",asMETHOD(NxActor,raiseActorFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setContactReportFlags(uint)",asMETHOD(NxActor,setContactReportFlags), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setContactReportThreshold(float)",asMETHOD(NxActor,setContactReportThreshold), asCALL_THISCALL);	 assert( r >= 0 );		
	r = engine->RegisterObjectMethod("NxActor","float getMass()",asMETHOD(NxActor,getMass), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","uint getNbShapes()",asMETHOD(NxActor,getNbShapes), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","NxShape@ getShape(int)",asFUNCTION(NxActor_getShape), asCALL_CDECL_OBJFIRST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setSleepLinearVelocity(float)",asMETHOD(NxActor,setSleepLinearVelocity), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setSleepAngularVelocity(float)",asMETHOD(NxActor,setSleepAngularVelocity), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setGroup(uint16)",asMETHOD(NxActor,setGroup), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","uint16 getGroup()",asMETHOD(NxActor,getGroup), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setCMassOffsetLocalPosition(const NxVec3&in)",asMETHOD(NxActor,setCMassOffsetLocalPosition), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","NxVec3 getCMassLocalPosition()",asMETHOD(NxActor,getCMassLocalPosition), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setMassSpaceInertiaTensor(const NxVec3&in)",asMETHOD(NxActor,setMassSpaceInertiaTensor), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","NxVec3 getMassSpaceInertiaTensor()",asMETHOD(NxActor,getMassSpaceInertiaTensor), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","bool updateMassFromShapes(float,float)",asMETHOD(NxActor,updateMassFromShapes), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void moveGlobalPosition (const NxVec3&in)",asMETHOD(NxActor,moveGlobalPosition), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxShape","NxActor& getActor()",asMETHOD(NxShape,getActor), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxActor","void setAngularVelocity(const NxVec3 &in )",asMETHOD(NxActor,setAngularVelocity), asCALL_THISCALL);	 assert( r >= 0 );

	//NxMaterial 
	r=engine->RegisterObjectType("NxMaterial",sizeof(NxMaterial), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(NxMaterial)
	r = engine->RegisterObjectMethod("NxMaterial","void setRestitution(float)",asFUNCTION(NxMaterial_setRestitution), asCALL_CDECL_OBJLAST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMaterial","void setStaticFriction(float)",asFUNCTION(NxMaterial_setStaticFriction), asCALL_CDECL_OBJLAST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMaterial","void setDynamicFriction(float)",asFUNCTION(NxMaterial_setDynamicFriction), asCALL_CDECL_OBJLAST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMaterial","float getRestitution()",asMETHOD(NxMaterial,getRestitution), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxMaterial","int getIndex()",asMETHOD(NxMaterial,getMaterialIndex), asCALL_THISCALL);	 assert( r >= 0 );

	///NxForceField
	r=engine->RegisterObjectType("NxForceField",sizeof(NxForceField), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(NxForceField)

	//NxScene
	r=engine->RegisterObjectType("NxScene",sizeof(NxScene), asOBJ_REF );	assert( r >= 0 );
	DECLARE_EMPTY_ADD_RELEASE_REF(NxScene)
	r = engine->RegisterObjectMethod("NxScene","NxActor @createActor(const NxActorDescBase& in)",asFUNCTION(NxScene_createActor), asCALL_CDECL_OBJLAST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxScene","NxMaterial @createMaterial(const NxMaterialDesc& in)",asMETHOD(NxScene,createMaterial), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxScene","NxMaterial @getMaterialFromIndex(uint16 matIndex)",asMETHOD(NxScene,getMaterialFromIndex), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxScene","void setGroupCollisionFlag(uint,uint,bool)",asMETHOD(NxScene,setGroupCollisionFlag), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxScene","void setActorPairFlags(NxActor& inout, NxActor& inout, NxContactPairFlag)",asMETHOD(NxScene,setActorPairFlags), asCALL_THISCALL);	 assert( r >= 0 );	

	r = engine->RegisterObjectMethod("NxScene","void releaseForceField(NxForceField& inout)",asMETHOD(NxScene,releaseForceField), asCALL_THISCALL);	 assert( r >= 0 );	
	r = engine->RegisterObjectMethod("NxScene","void setGravity(const NxVec3&in)",asMETHOD(NxScene,setGravity), asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod("NxScene","void setActorGroupPairFlags(uint16,uint16,uint)",asMETHOD(NxScene,setActorGroupPairFlags), asCALL_THISCALL);	 assert( r >= 0 );

	///ActorGroup
	r=engine->RegisterEnum("ActorGroup"); assert( r >= 0 );
	r=engine->RegisterEnumValue("ActorGroup","Actor_Group_Default",Actor_Group_Default);
	r=engine->RegisterEnumValue("ActorGroup","Actor_Group_Terrain",Actor_Group_Terrain);
	r=engine->RegisterEnumValue("ActorGroup","Actor_Group_Plane",Actor_Group_Plane);

	//物理关节 暂时不绑定
	////NxJoint
	//r=engine->RegisterObjectType("NxJoint",sizeof(NxJoint), asOBJ_REF);	assert( r >= 0 ); 
	//DECLARE_EMPTY_ADD_RELEASE_REF(NxJoint)
	//TYPEMETHODS(NxJoint)

	////NxSphericalJoint
	//r=engine->RegisterObjectType("NxSphericalJoint",sizeof(NxSphericalJoint), asOBJ_REF);	assert( r >= 0 ); 
	//DECLARE_EMPTY_ADD_RELEASE_REF(NxSphericalJoint)

	////NxJointDriveDesc
	//r = engine->RegisterObjectType("NxJointDriveDesc", sizeof(NxJointDriveDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( r >= 0 );
	//DECLARE_CONSTRUCTOR(NxJointDriveDesc)
	//r = engine->RegisterObjectProperty("NxJointDriveDesc", "float spring", offsetof(NxJointDriveDesc,spring)); assert( r >= 0 );
	//r = engine->RegisterObjectProperty("NxJointDriveDesc", "float damping", offsetof(NxJointDriveDesc,damping)); assert( r >= 0 ); 

	/////NxD6JointDesc
	//r = engine->RegisterObjectType("NxD6JointDesc", sizeof(NxD6JointDesc), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_C); assert( r >= 0 );
	//DECLARE_CONSTRUCTOR(NxD6JointDesc)
	//TYPEMETHODS(NxD6JointDesc)

	////NxD6Joint
	//r=engine->RegisterObjectType("NxD6Joint",sizeof(NxD6Joint), asOBJ_REF);	assert( r >= 0 ); 
	//DECLARE_EMPTY_ADD_RELEASE_REF(NxD6Joint)
	//DECLARE_DERIVE(NxD6Joint,NxJoint)
	//TYPEMETHODS(NxD6Joint)

	////NxContactPair
	//r = engine->RegisterObjectType("NxContactPair", sizeof(NxContactPair), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS); assert( r >= 0 );		
	//DECLARE_CONSTRUCTOR(NxContactPair)	
	//r = engine->RegisterObjectProperty("NxContactPair", "NxActor @actors1", offsetof(NxContactPair,actors)); assert( r >= 0 );
	//r = engine->RegisterObjectProperty("NxContactPair", "NxActor @actors2", offsetof(NxContactPair,actors)+4); assert( r >= 0 );
}

_NAMESPACE_END

